home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
001-100
/
001-025
/
020
/
hd
/
hd.c
next >
Wrap
C/C++ Source or Header
|
1995-03-17
|
13KB
|
383 lines
/* Dump files, similar to OD, but in a different format
* Files are displayed sixteen bytes to a line, offset from the beginning
* of the file on the right, hex values in the middle,
* ascii values on the right.
* -c option displays char value above hex value
* 13 May 1985 David Elins
*/
/* modifications
* 3-28-86 uses different formats depending on how bytes are ordered
* on the machine
* little-endian (e.g. vax)
* hex ..... hex addr ascii
* big endian (e.g. 68000)
* addr hex ascii
*
* idea came from an article by Mike Higgins
* in "Computer Language" April, 1986
*
* 3-30-86 -x option reverses natural display format
*
* 4-14-86 Amiga port for both Lattice and Manx (under 32 bit)
*
* screen width needs to be a define
* fputs not documented to return valid value except on error
* printf return value cannot be relied on under Lattice
* modify isprint semantics to limit to "normal" ascii
*
*/
#include <stdio.h>
#include <ctype.h>
extern char *strrchr();
extern void exit();
#define EQS(str1,str2) (strcmp((str1),(str2))==0)
/*
* On the Amiga, the normal CLI window is only 77 characters wide.
* I decided to trim the line length by recovering 3 characters from
* the offset field. Fred Fish 14-Apr-86
*/
#ifdef AMIGA
#define OFFSETFMT "%05lx"
#define OFFSETSIZ (5) /* Should match length in OFFSETFMT */
#define WIDTH (77) /* Screen width in char positions */
#define BLANKS " "
#define ISPRINT(x) (((x) < 0200) && isprint(x)) /* Limit to 000-177 */
extern int Enable_Abort;
#else
#define OFFSETFMT "%08lx"
#define OFFSETSIZ (8)
#define WIDTH (80)
#define BLANKS " "
#define ISPRINT(x) isprint(x)
#endif
static int showchar=0;
static int manyfile;
main(argc, argv)
int argc;
char *argv[];
{
#ifdef MSDOS
char *pgmname="hd"; /* Microsoft C may not support argv[0] */
#else
extern char *basename(); /* pathnames allowed on commands */
char *pgmname=basename(argv[0]);
#endif
int lowfirst(),highfirst(); /* dump formatting routines */
static int reverse = 0; /* reverse natural display format */
register char *cp, c;
#ifdef AMIGA
Enable_Abort = 1; /* Stupid Lattice default is 0 */
#endif
/* parse options */
for (; argc > 1 && (*argv[1] == '-'); argv++, argc--) {
cp = &argv[1][1]; /* - alone is standard input */
while ((c = *cp++) && argc) {
switch (c) {
case 'c': /* like od -c option */
showchar = 1;
break;
case 'x': /* reverse natural display format */
reverse = 1;
break;
default:
argc=0; /* modify argument to indicate error */
break;
}
}
}
if (argc < 1) {
(void)fprintf(stderr,"Usage: %s [-cx] [files]\n", pgmname);
exit(1);
}
manyfile = (argc > 2); /* more than one file to display? */
/* loop through filename arguments
if reverse == 1, exclusive or'ing with it
will reverse the return value of bytorder()
*/
if (bytorder() ^ reverse) /* display in natural or reversed order */
exit(filter(argc,argv,lowfirst));
else
exit(filter(argc,argv,highfirst));
}
/* format and display contents of stdin */
/* low addr byte of multibyte values is MOST significant */
static int
highfirst(filename) /* format and display contents of stdin */
char *filename;
{
unsigned char /* is unsigned char portable ? */
buf[16], /* portion of file read */
*bufptr, /* pointer into that portion */
ascstr[17], /* ascii equivalents of digits */
*pascstr; /* pointer into above string */
int ctr, /* general counter */
col, /* current column printed */
rlen; /* length read */
long offset=0L; /* offset from beginning of file */
static char sep[]="::::::::::::::"; /* separates filenames */
if (manyfile)
(void)printf("%s\n%s\n%s\n", sep, filename, sep);
/* read a display line's worth at a time, format and display it */
while ((rlen = fread(buf, sizeof(char), sizeof(buf), stdin)) > 0) {
col = 1;
bufptr = buf; /* point to beginning of bytes read */
if (showchar) { /* print equivalent characters above hex values? */
(void)fputs(BLANKS, stdout); /* for offset into file; */
for (ctr = 0; ctr < rlen; ctr++) {
if (ctr % 4 == 0)
(void)fputs(" ",stdout); /* separate each four bytes */
(void)fputs(" ",stdout);
if (*bufptr == '\b')
(void)fputs("\\b",stdout);
else if (*bufptr == '\t')
(void)fputs("\\t",stdout);
else if (*bufptr == '\n')
(void)fputs("\\n",stdout);
else if (*bufptr == '\f')
(void)fputs("\\f",stdout);
else if (*bufptr == '\r')
(void)fputs("\\r",stdout);
else if (ISPRINT(*bufptr))
(void)printf(" %c", *bufptr);
else
(void)fputs(" ",stdout);
bufptr++;
}
(void)putc('\n',stdout);
}
bufptr = buf; /* point to beginning of bytes read */
pascstr = ascstr; /* point to beginning of ascii equivalents */
(void) printf(OFFSETFMT, offset); /* count and print offset into file; */
col += OFFSETSIZ;
for (ctr = 0; ctr < rlen; ctr++) {
if (ctr % 4 == 0) {
col++; /* fputs value defined only on error */
(void)fputs(" ",stdout); /* separate each four bytes */
}
*pascstr++ = ISPRINT(*bufptr) ? *bufptr : '.'; /* save ascii val */
(void) printf(" %02x", *bufptr++); /* display hex value of byte */
col += 3;
}
*pascstr = '\0'; /* terminate ascii string */
do {
(void)fputs(" ",stdout); /* fputs value defined only on error */
} while (col++ < (WIDTH-18)); /* align ascii values */
(void)printf("|%s|\n",ascstr); /* display ascii values */
offset += rlen; /* bump offset into file */;
}
return (1);
}
/* format and display contents of stdin */
/* low addr byte of multibyte values is LEAST significant */
static int
lowfirst(filename) /* format and display contents of stdin */
char *filename;
{
unsigned char /* is unsigned char portable ? */
buf[16], /* portion of file read */
*bufptr, /* pointer into that portion */
*rbufptr, /* backward pointer into that portion */
ascstr[17], /* ascii equivalents of digits */
*pascstr; /* pointer into above string */
int ctr, /* general counter */
col, /* current column printed */
rlen; /* length read */
long offset=0L; /* offset from beginning of file */
static char sep[]="::::::::::::::"; /* separates filenames */
if (manyfile)
(void)printf("%s\n%s\n%s\n", sep, filename, sep);
/* read a display line's worth at a time, format and display it */
while ((rlen = fread(buf, sizeof(char), sizeof(buf), stdin)) > 0) {
col = 1; /* current printed column */
rbufptr = buf + rlen - 1; /* point to end of bytes read */
if (showchar) { /* print equivalent characters above hex values? */
for (ctr = 0; ctr < sizeof(buf); ctr++) {
if ((ctr + rlen) < sizeof(buf))
(void)fputs(" ",stdout);
else if (*rbufptr == '\b')
(void)fputs("\\b",stdout);
else if (*rbufptr == '\t')
(void)fputs("\\t",stdout);
else if (*rbufptr == '\n')
(void)fputs("\\n",stdout);
else if (*rbufptr == '\f')
(void)fputs("\\f",stdout);
else if (*rbufptr == '\r')
(void)fputs("\\r",stdout);
else if (ISPRINT(*rbufptr))
(void)printf(" %c", *rbufptr);
else
(void)fputs(" ",stdout);
if (ctr % 4 == 3)
(void)fputs(" ",stdout); /* separate each four bytes */
(void)fputs(" ",stdout);
if ((ctr + rlen) >= sizeof(buf))
rbufptr--;
}
(void)putc('\n',stdout);
}
bufptr = buf; /* point to beginning of bytes read */
rbufptr = buf + rlen - 1; /* point to end of bytes read */
pascstr = ascstr; /* point to beginning of ascii equivalents */
for (ctr = 0; ctr < sizeof(buf); ctr++) {
if ((ctr + rlen) < sizeof(buf)) { /* display hex value of byte */
(void) fputs(" ",stdout); /* no value */
} else {
(void) printf("%02x ", *rbufptr);
}
col += 3;
if (ctr % 4 == 3) {
col++;
(void) fputs(" ",stdout); /* separate each four bytes */
}
if ((ctr + rlen) >= sizeof(buf)) { /* save ascii value */
*pascstr++ = ISPRINT(*bufptr) ? *bufptr : '.';
bufptr++; /* advance, */
rbufptr--; /* decrement pointers */
}
}
*pascstr = '\0'; /* terminate ascii string */
(void) printf(OFFSETFMT,offset); /* count and print offset into file; */
col += OFFSETSIZ;
do {
(void)fputs(" ",stdout); /* fputs value defined only on error */
} while (col++ < (WIDTH-18)); /* align ascii values */
(void)printf("|%s|\n",ascstr); /* display ascii values */
offset += rlen; /* bump offset into file */;
}
return (1);
}
/* is low addr byte of multi-byte values the least significant ? */
static int
bytorder()
{
static union { /* used to determine byte order */
int x;
char c[2];
} test;
test.x=1; /* find out how bytes are ordered */
return(test.c[0] == test.x);
}
/*
* perform the basename(1) function from a C program
*/
static
char *
basename(name) /* return pointer to filename portion of name */
char name[];
{
char *cp=strrchr(name,'/');
return(cp==NULL ? name : (cp+1));
}
/*
* loop through filenames on a command line
* reopening each as standard input
*/
extern int errno; /* system error variable */
extern void perror();
static
int
filter(argc,argv,process)
int argc; /* how many command line arguments */
char *argv[]; /* command line arguments */
int (*process)();/* function that processes each file, called at least once */
/* the only argument is the filename (NULL if orig stdin) */
{
#ifdef unix
register int fd = dup(0); /* initial standard input */
#endif
register int inorig; /* 0=from stdin, else from file */
register int firstime; /* make sure *process is called once */
register int retval=0; /* return value */
for (firstime = 1; firstime || (argc > 1); argc--,argv++,firstime=0) {
/* arguments are filenames to filter, "-" means standard input */
inorig = ((argc == 1) || EQS(argv[1],"-"));
if (inorig) {
#ifdef unix
(void)close(0); /* reset to initial standard input */
(void)dup(fd);
#endif
}
/* set filename as standard input */
else if (freopen(argv[1],"r",stdin) == NULL) {
char string[48];
retval = errno; /* return if error */
(void)sprintf(string,"cannot open %s", argv[1]);
perror(string);
break;
}
(*process)(inorig?(char *)NULL:argv[1]); /* process this file */
}
if (!inorig) { /* leave stdin the same file as at entry */
#ifdef unix
(void)close(0);
(void)dup(fd);
#endif
}
return(retval);
}
#ifdef MANX
char *strrchr (s, c)
char *s;
char c;
{
register char *scan;
scan = s;
while (*scan++ != '\000') {;}
while (--scan > s && *scan != c) {;}
return (*scan == c ? scan : NULL);
}
#endif /* MANX */
#ifdef AMIGA /* Neither Lattice or Manx has perror */
void perror (sp)
char *sp;
{
if (sp && *sp) {
fprintf (stderr, "%s: ", sp);
}
fprintf (stderr, "<unknown error>\n");
}
#endif /* AMIGA */